#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<unordered_set>
using namespace std;

struct ListNode {
    int val;
    ListNode* next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode* next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return sortList(head, nullptr);
    }

    ListNode* sortList(ListNode* head, ListNode* tail)
    {
        if (head == nullptr) return head;
        if (head->next == tail)
        {
            head->next = nullptr;
            return head;
        }
        ListNode* slow = head, * fast = head;
        while (fast != tail)
        {
            slow = slow->next;
            fast = fast->next;
            if (fast != tail)
                fast = fast->next;
        }
        ListNode* mid = slow;
        return mergesort(sortList(head, mid), sortList(mid, tail));
    }

    ListNode* mergesort(ListNode* head1, ListNode* head2)
    {
        ListNode* dummy = new ListNode(-1);
        ListNode* cur = dummy, * cur1 = head1, * cur2 = head2;
        while (cur1 != nullptr && cur2 != nullptr)
        {
            if (cur1->val > cur2->val)
            {
                cur->next = cur2;
                cur2 = cur2->next;
            }
            else
            {
                cur->next = cur1;
                cur1 = cur1->next;
            }
            cur = cur->next;
        }
        if (cur1 != nullptr)
            cur->next = cur1;
        if (cur2 != nullptr)
            cur->next = cur2;
        return dummy->next;
    }

    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        vector<vector<int>> ret;
        ret.push_back(intervals[0]);
        for (int i = 1; i < intervals.size(); ++i)
        {
            if (intervals[i][0] > ret.back()[1]) ret.push_back(intervals[i]);
            else
                ret.back()[1] = intervals[i][1] > ret.back()[1] ? intervals[i][1] : ret.back()[1];
        }
        return ret;
    }

    void func()
    {
        long long m, n, a, b;
        cin >> n >> m >> a >> b;
        long long l = min(n / 2, m);
        long long ans = 0;
        for (long x = 0; x <= l; ++x)
        {
            long long y = min(n - 2 * x, (m - x) / 2);
            ans = max(ans, a * x + b * y);
        }
        cout << ans;
    }

    void reverse_string()
    {
        string s;
        getline(cin, s);
        reverse(s.begin(), s.end());
        int left = 0, n = s.size();
        while (left < n)
        {
            int right = left;
            while (right < n && s[right] != ' ') ++right;
            reverse(s.begin() + left, s.begin() + right);
            while (right < n && s[right] == ' ') ++right;
            left = right;
        }
        cout << s;
    }

    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> st(wordDict.begin(), wordDict.end());
        int n = s.size();
        vector<bool> dp(n + 1);
        dp[0] = true;
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 0; j < i; ++j)
            {
                if (dp[i] = (dp[j] && st.find(s.substr(j, i - j)) != st.end()))
                    break;
            }
        }
        return dp[n];
    }
};